package com.example.hello.views;

import com.example.hello.*;
import com.example.hello.POJO.UserPOJO;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.ShortcutAction;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.ui.AbstractTextField;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

import java.io.IOException;

public class LogIn extends VerticalLayout implements View {

    public static final String NAME = "login";

    HorizontalLayout layout = new HorizontalLayout();
    BootstrapTabPanel panel = new BootstrapTabPanel(BootstrapTabPanel.Position.ABOVE);
    BootstrapTabLink logInLink = new BootstrapTabLink("Log In");
    BootstrapTabPane logInPane = new BootstrapTabPane();
    BootstrapTabLink signUpLink = new BootstrapTabLink("Sign Up");
    BootstrapTabPane signUpPane = new BootstrapTabPane();

    // LogIn fields
    final TextField userName = new TextField();
    final PasswordField password = new PasswordField();

    final BootstrapButton logInSubmit = new BootstrapButton("Submit");

    // SignUp fields
    final TextField firstName = new TextField();
    final TextField lastName = new TextField();
    final TextField screenName = new TextField();
    final PasswordField password1 = new PasswordField();
    final PasswordField password2 = new PasswordField();

    final BootstrapButton signUpSubmit = new BootstrapButton("Submit");

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        logInLink.setActive(true);
        logInLink.getTabPane().setActive(true);
    }

    public LogIn() {
        setSizeFull();
        addComponent(layout);
        layout.setSizeFull();

        initTabPanel();
        initLogIn();
        initSignUp();

        layout.addComponent(panel);
        layout.setExpandRatio(panel, 1);
    }

    public void initTabPanel() {
        panel.setSizeFull();

        // link the tabLinks to the tabPanes
        logInLink.setTabPane(logInPane);
        logInPane.setHref("logIn");
        logInLink.setDataTarget("logIn");
        signUpLink.setTabPane(signUpPane);
        signUpPane.setHref("signUp");
        signUpLink.setDataTarget("signUp");

        panel.addTab(logInLink);
        panel.addTab(signUpLink);
        panel.addTab(logInPane);
        panel.addTab(signUpPane);

        logInLink.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                getUI().getNavigator().navigateTo(LogIn.NAME);
            }
        });
        signUpLink.addListener(new Listener() {
            @Override
            public void componentEvent(Event event) {
                getUI().getNavigator().navigateTo(SignUp.NAME);
            }
        });
    }

    public void initLogIn() {
        VerticalLayout logInLayout = new VerticalLayout();
        Listener logIn = new Listener() {
            @Override
            public void componentEvent(Event event) {
                logIn();
            }
        };
        logInSubmit.addListener(logIn);

        enterKeyHandler(logInSubmit, userName);
        enterKeyHandler(logInSubmit, password);

        userName.setCaption("Username");
        logInLayout.addComponent(userName);
        password.setCaption("Password");
        logInLayout.addComponent(password);
        logInLayout.addComponent(new VSpacer(5));
        logInLayout.addComponent(logInSubmit);
        logInPane.addWidget(logInLayout);
    }

    public void initSignUp() {
        VerticalLayout signUpLayout = new VerticalLayout();
        Listener signUp = new Listener() {
            @Override
            public void componentEvent(Event event) {
                if (password1.equals(password2)) {
                    signUp();
                } else {
                    getUI().getNavigator().navigateTo(LogIn.NAME);
                }
            }
        };
        signUpSubmit.addListener(signUp);

        enterKeyHandler(signUpSubmit, firstName);
        enterKeyHandler(signUpSubmit, lastName);
        enterKeyHandler(signUpSubmit, screenName);
        enterKeyHandler(signUpSubmit, password1);
        enterKeyHandler(signUpSubmit, password2);

        firstName.setCaption("First Name");
        signUpLayout.addComponent(firstName);
        lastName.setCaption("Last Name");
        signUpLayout.addComponent(lastName);
        screenName.setCaption("Username");
        signUpLayout.addComponent(screenName);
        signUpLayout.addComponent(new VSpacer());
        password1.setCaption("Password");
        signUpLayout.addComponent(password1);
        password2.setCaption("Confirm Password");

        signUpLayout.addComponent(password2);
        signUpLayout.addComponent(new VSpacer(5));
        signUpLayout.addComponent(signUpSubmit);
        signUpPane.addWidget(signUpLayout);
    }

    private void enterKeyHandler(final BootstrapButton button, final AbstractTextField... fields) {
        for (AbstractTextField field : fields) {
            field.addFocusListener(new FieldEvents.FocusListener() {
                public void focus(final FieldEvents.FocusEvent event) {
                    button.setClickShortcut(ShortcutAction.KeyCode.ENTER);
                }
            });
            field.addBlurListener(new FieldEvents.BlurListener() {
                @Override
                public void blur(final FieldEvents.BlurEvent event) {
                    button.removeClickShortcut();
                }
            });
        }
    }

    public boolean logIn() {
        UserPOJO user = new UserPOJO();
        try {
            String get = HttpRequest.executeGet("http://localhost:8080/", "users/" + userName.getValue());
            ObjectMapper mapper = new ObjectMapper();
            user = mapper.readValue(get, UserPOJO.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (user.getUserName().equals(userName.getValue()) && user.getPassword().equals(password.getValue())) {
            ((HelloUI) HelloUI.getCurrent()).setUser(user);
            ((HelloUI) HelloUI.getCurrent()).setLoginFlag(true);
            getUI().getSession().setAttribute("isLoggedIn", "true");
//            getUI().getNavigator().addView(Profile.NAME = "users/" + userName.getValue(), Profile.class);
            getUI().getNavigator().navigateTo(Wireframe1.NAME);
            return true;
        } else {
            addComponent(new BootstrapAlert("Invalid", BootstrapAlert.AlertType.ERROR), 0);
            userName.setValue("");
            password.setValue("");
            return false;
        }
    }

    public boolean signUp() {
        ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
        String json = "";
        try {
            json = ow.writeValueAsString(new UserPOJO(firstName.getValue(), lastName.getValue(), screenName.getValue(), password1.getValue()));
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (HttpRequest.executePost("http://localhost:8080/", "users/", json) &&
                password1.getValue().equals(password2.getValue())) {
            String get = HttpRequest.executeGet("http://localhost:8080/", "users/" + screenName.getValue());
            ObjectMapper mapper = new ObjectMapper();
            try {
                ((HelloUI) HelloUI.getCurrent()).setUser(mapper.readValue(get, UserPOJO.class));
            } catch (IOException e) {
                e.printStackTrace();
            }
            ((HelloUI) HelloUI.getCurrent()).setLoginFlag(true);
            getUI().getSession().setAttribute("isLoggedIn", "true");
//            getUI().getNavigator().addView(Profile.NAME = "users/" + screenName.getValue(), Profile.class);
            getUI().getNavigator().navigateTo(Wireframe1.NAME);
            return true;
        } else {
            addComponent(new BootstrapAlert("Invalid", BootstrapAlert.AlertType.ERROR), 0);
            if (!password1.getValue().equals(password2.getValue())) {
                password1.setValue("");
                password2.setValue("");
            } else {
                screenName.setValue("");
            }
            return false;
        }
    }

}